package com.neo.config;

import com.changxin.GeneralPackage.Constants;
import com.changxin.GeneralPackage.vo.ResultEntity;
import com.neo.entity.UserInfo;
import com.neo.sevice.UserInfoService;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

import javax.annotation.Resource;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;
import static com.changxin.GeneralPackage.utils.CommonUtil.isNullOrEmpty;

/**
 * @author liuhuan
 * @create 2018-08-23 13:46
 **/
public class StatelessAccessControlFilter  extends AccessControlFilter {

    private static final String SHIRO_LOGIN_COUNT = "SHIRO_LOGIN_COUNT";
    private static final String SHIRO_IS_LOCK = "SHIRO_IS_LOCK";

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private UserInfoService userservice;

    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception {
        System.out.println("isAccessAllowed");
        return false;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
        System.out.println("onAccessDenied");

        String userAccount = servletRequest.getParameter("username");
        String password = servletRequest.getParameter("password");

        System.out.println("身份认证方法：MyShiroRealm.doGetAuthenticationInfo()");

        ValueOperations<String, String> opsForValue = stringRedisTemplate.opsForValue();
        if ("LOCK".equals(opsForValue.get(SHIRO_IS_LOCK + userAccount))) {
            throw new DisabledAccountException("由于密码输入错误次数大于5次，帐号已经禁止登录！");
        }

        //访问一次，计数一次
//        opsForValue.set(SHIRO_LOGIN_COUNT + userAccount, "0");
        opsForValue.increment(SHIRO_LOGIN_COUNT + userAccount, 1);
        System.out.println("错了----" + opsForValue.get(SHIRO_LOGIN_COUNT + userAccount) + "次数");

        //计数大于5时，设置用户被锁定一小时
        if (Integer.parseInt(opsForValue.get(SHIRO_LOGIN_COUNT + userAccount)) >= 5) {
            opsForValue.set(SHIRO_IS_LOCK + userAccount, "LOCK");
            String lockTime = String.valueOf(stringRedisTemplate.expire(SHIRO_IS_LOCK + userAccount, 2, TimeUnit.MINUTES));
            ResultEntity resultEntity = new ResultEntity();
            resultEntity.setFlag("" + Constants.resultFlagEnum.failed.getIndex());
            resultEntity.setMessage(userAccount);
            HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
            httpResponse.setCharacterEncoding("UTF-8");
            httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            httpResponse.getWriter().write(resultEntity.toString());
            resultEntity.setMessage("当前账户已被锁定，请在" + lockTime + "分钟后重试或联系系统管理员");
        }

        UserInfo userInfo = userservice.findByUsername(userAccount);
        try {
            if (isNullOrEmpty(userAccount)) {
                ResultEntity resultEntity = new ResultEntity();
                resultEntity.setFlag("" + Constants.resultFlagEnum.failed.getIndex());
                resultEntity.setMessage("用户账号不允许为空!");
                HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
                httpResponse.setCharacterEncoding("UTF-8");
                httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                httpResponse.getWriter().write(resultEntity.toString());

                return false;
            }
            if(!userInfo.getUsername().equals(userAccount)){

                ResultEntity resultEntity = new ResultEntity();
                resultEntity.setFlag("" + Constants.resultFlagEnum.failed.getIndex());
                resultEntity.setMessage("用户账号不存在!");
                HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
//                httpResponse.setCharacterEncoding("UTF-8");
                httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                httpResponse.getWriter().write(resultEntity.toString());
                return false;

            }
            if(!userInfo.getPassword().equals(password)){
                ResultEntity resultEntity = new ResultEntity();
                resultEntity.setFlag("" + Constants.resultFlagEnum.failed.getIndex());
                resultEntity.setMessage("密码错误!");
                HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
//                httpResponse.setCharacterEncoding("UTF-8");
                httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                httpResponse.getWriter().write(resultEntity.toString());
                return false;
            }
        }catch (Exception e) {
//            logger.error(getStackTraceFromException(e));
            ResultEntity resultEntity = new ResultEntity();
            resultEntity.setFlag("" + Constants.resultFlagEnum.failed.getIndex());
            resultEntity.setMessage(e.getMessage());
            HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
            httpResponse.setCharacterEncoding("UTF-8");
            httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            httpResponse.getWriter().write(resultEntity.toString());

            return false;
        }
        // 每次登录成功后重置账户的登录次数
        opsForValue.set(SHIRO_LOGIN_COUNT + userAccount, "0");
        return false;

    }
}
